#include <iostream>
#include <string>
#include <string.h>

using namespace std;

// 赋值运算符重载：=、>>、<<
class String
{
    char* data;
    int length;
public:
    String(): data(nullptr), length(0)
    {}
    String(const char* str)
    {
        length = strlen(str);
        data = new char[length + 1];
        strcpy(data, str);
    }
    ~String()
    {
        delete[] data;
    }
    String& operator=(const String& other)
    {
        if(*data != *other.data)
        {
            delete[] data;
            length = other.length;
            data = new char[length + 1];
            strcpy(data, other.data);
        }
        return *this;
    }
    // 考虑到>>和<<的第一个参数不能为this指针，否则用起来和内置类型的使用不一致，所以使用友元
    friend istream& operator>>(istream& is, String& str);
    friend ostream& operator<<(ostream& os, String& str);
};

istream& operator>>(istream& is, String& str)
{
    delete[] str.data;
    str.data = nullptr;
    str.length = 0;

    const size_t BUFFER_SIZE = 256;
    char buffer[BUFFER_SIZE];
    if(is.getline(buffer, BUFFER_SIZE))
    {
        str.length = strlen(buffer);
        str.data = new char[str.length + 1];
        strcpy(str.data, buffer);
    }
    return is;
}

ostream& operator<<(ostream& os, String& str)
{
    if(str.data != nullptr)
    {
        os << str.data;
    }
    return os;
}

// 前置++与后置++
class Counter
{
public:
    int value;
public:
    Counter():value(0)
    {}
    // ++i
    Counter& operator++()
    {
        ++value;
        return *this;
    }
    // i++
    Counter& operator++(int)
    {
        Counter tmp = *this;
        value++;
        return tmp;
    }
};

// 重载能够检测是否越界的[]
class IntArray
{
    int* a;
    int size;
public:
    int& operator[](int index)
    {
        if(index < 0 || index >= size)
        {
            throw std::out_of_range("index out of range!");
        }
        return a[index];
    }
    const int& operator[](int index) const
    {
        if(index < 0 || index >= size)
        {
            throw std::out_of_range("index out of range!");
        }
        return a[index];
    }
};

// 运算符重载：*和->
template<class T>
class smartPtr
{
    T* ptr;
public:
    smartPtr(T* p = nullptr): ptr(p)
    {}
    ~smartPtr()
    {
        delete ptr;
    }
    T& operator*()
    {
        return *ptr;
    }
    T* operator->()
    {
        return ptr;
    }
};
int main()
{
    // String s;
    // cin >> s;
    // cout << s << endl;
    // Counter cter;
    // cter++;
    // cout << cter.value << endl;
    smartPtr<string> pstr(new string("hello"));
    cout << *pstr << endl;
    cout << pstr->size() << endl;
    return 0;
}